"""
Created on 16 Dec 2020
@author:JemusD
instruction: 
    她这个不必手写分类器classify()，而是直接调用的sklearn中的。如下：
    neigh = KNN(n_neighbor=k, algorithm='auto')
    neigh.fit(trainMatrix, Labels)

    predictResult = neigh.predict(inX)
"""
import numpy as np
from os import listdir
from sklearn.neighbors import KNeighborsClassifier as KNN

# 将图片矩阵转成行向量
def image2vector(filename):
    fr = open(filename)
    returnVect = np.zeros((1,1024))

    for i in range(32):
        # i从0开始
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0, 32*i+j] = int(lineStr[j])
    return returnVect


"""
instructions: 手写识别函数
    hwLabels - 手写数字标签
    trainingFilesList - 打开目录后，该文件夹下的文件列表
    os.listdir() - 列出给定目录的文件名
Parameters: 
    None
Returns:
    None
Modify:
    2020-12-17
"""
def handWritingClassTest():
    hwLabels = []
    trainingFilesList = listdir('trainingDatas')
    m = len(trainingFilesList)
    trainingMat = np.zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFilesList[i]
        # x = 'abcdef' x[0] -> 'a'
        classNumber = int(fileNameStr.split('_')[0])
        hwLabels.append(classNumber)
        # 以上为labels提取，从文件名字提取其right answer: 5_78.txt -> 5
        trainingMat[i,:] = image2vector('trainingDatas/%s' % (fileNameStr))
        
    neigh = KNN(n_neighbors=3, algorithm='auto')
    neigh.fit(trainingMat, hwLabels)
       
    testFileList = listdir('testDatas')
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        classNumber = int(fileNameStr.split('_')[0])
        vectorUnderTest = image2vector('testDatas/%s' % (fileNameStr))
        classifierResult = neigh.predict(vectorUnderTest)
        print("the result of classifier:%d\t the true value is:%d" % (classifierResult, classNumber))
        if(classifierResult != classNumber):
            errorCount += 1.0
        
    print("the total error:%d\nerror ratio is:%f%%" % (errorCount, errorCount/mTest * 100))


def main():
    handWritingClassTest()

if __name__ == '__main__':
    main()
# dingpengda come from china
